﻿using System;

public class ChannelTriangle : PapuChannel
{
    internal bool isEnabled_Renamed_Field;
    internal bool lcControl;
    internal bool lcHalt;
    internal int lcLoadValue;
    internal int lengthCounter;
    internal bool lengthCounterEnable;
    internal int linearCounter;
    internal PAPU papu;
    internal int progTimerCount;
    internal int progTimerMax;
    internal bool sampleCondition;
    internal int sampleValue;
    internal int tmp;
    internal int triangleCounter;

    public ChannelTriangle(PAPU papu)
    {
        this.papu = papu;
    }

    public virtual void clockLengthCounter()
    {
        if (this.lengthCounterEnable && (this.lengthCounter > 0))
        {
            this.lengthCounter--;
            if (this.lengthCounter == 0)
            {
                this.updateSampleCondition();
            }
        }
    }

    public virtual void clockLinearCounter()
    {
        if (this.lcHalt)
        {
            this.linearCounter = this.lcLoadValue;
            this.updateSampleCondition();
        }
        else if (this.linearCounter > 0)
        {
            this.linearCounter--;
            this.updateSampleCondition();
        }
        if (!this.lcControl)
        {
            this.lcHalt = false;
        }
    }

    public virtual void clockProgrammableTimer(int nCycles)
    {
        if (this.progTimerMax > 0)
        {
            this.progTimerCount += nCycles;
            while ((this.progTimerMax > 0) && (this.progTimerCount >= this.progTimerMax))
            {
                this.progTimerCount -= this.progTimerMax;
                if ((this.isEnabled_Renamed_Field && (this.lengthCounter > 0)) && (this.linearCounter > 0))
                {
                    this.clockTriangleGenerator();
                }
            }
        }
    }

    public virtual void clockTriangleGenerator()
    {
        this.triangleCounter++;
        this.triangleCounter &= 0x1f;
    }

    public virtual void destroy()
    {
        this.papu = null;
    }

    public virtual int readReg(int address)
    {
        return 0;
    }

    public virtual void reset()
    {
        this.progTimerCount = 0;
        this.progTimerMax = 0;
        this.triangleCounter = 0;
        this.isEnabled_Renamed_Field = false;
        this.sampleCondition = false;
        this.lengthCounter = 0;
        this.lengthCounterEnable = false;
        this.linearCounter = 0;
        this.lcLoadValue = 0;
        this.lcHalt = true;
        this.lcControl = false;
        this.tmp = 0;
        this.sampleValue = 15;
    }

    public virtual void updateSampleCondition()
    {
        this.sampleCondition = ((this.isEnabled_Renamed_Field && (this.progTimerMax > 7)) && (this.linearCounter > 0)) && (this.lengthCounter > 0);
    }

    public virtual void writeReg(int address, int value_Renamed)
    {
        if (address == 0x4008)
        {
            this.lcControl = (value_Renamed & 0x80) != 0;
            this.lcLoadValue = value_Renamed & 0x7f;
            this.lengthCounterEnable = !this.lcControl;
        }
        else if (address == 0x400a)
        {
            this.progTimerMax &= 0x700;
            this.progTimerMax |= value_Renamed;
        }
        else if (address == 0x400b)
        {
            this.progTimerMax &= 0xff;
            this.progTimerMax |= (value_Renamed & 7) << 8;
            this.lengthCounter = this.papu.getLengthMax(value_Renamed & 0xf8);
            this.lcHalt = true;
        }
        this.updateSampleCondition();
    }

    public virtual bool Enabled
    {
        get
        {
            return this.isEnabled_Renamed_Field;
        }
        set
        {
            this.isEnabled_Renamed_Field = value;
            if (!value)
            {
                this.lengthCounter = 0;
            }
            this.updateSampleCondition();
        }
    }

    public virtual int LengthStatus
    {
        get
        {
            if ((this.lengthCounter != 0) && this.isEnabled_Renamed_Field)
            {
                return 1;
            }
            return 0;
        }
    }
}

